
#include "IMode.h"
#include <iostream>

using namespace controller;

// 1.发送->不接收
int IMode::S1(LinkBase *l, PacketBase *p)
{
    int size = 0, rsize = 0;
    if (l && p)
    {
        void *arg = NULL;
        char buf[PacketBase::BUFFER_MAX];

        size = p->to_bytes(buf, &arg);
        if (size > 0)
            rsize = l->write(buf, size, (const char *)arg);
    }
    return rsize;
}

int IMode::S1(LinkBase *l, PacketBuild p)
{
    int size = 0;
    if (l && p)
    {
        PacketBase *pk = p(l);
        if (pk)
        {
            size = IMode::S1(l, pk);
            delete pk;
        }
    }
    return size;
}

// 2. 发送 ->接收(阻塞)
int IMode::S2(LinkBase *l, PacketBase *p, PacketBase *r, PacketGet g, int g_timeout_ms, PacketTimeout tfn)
{
    int size = 0;
    if (l && p && r)
    {
        // 1接收事件
        PacketBase *rp = NULL;
        l->OnLinkRecv = [&](LinkBase *link, LinkBuffer *buf, const char *arg)
        {
            rp = r->on_get((char *)buf->data(), buf->size(), (void *)arg);
            if (rp != NULL)
            {
                std::cout << "接收到一个数据包" << std::endl;
            }
        };
        // 2.发送数据
        size = IMode::S1(l, p);

        // 3.阻塞等等数据包应答
        if (g_timeout_ms > 0)
        {
            int ms = 0;
            while (ms < g_timeout_ms)
            {
                usleep(10000);
                ms += 10;
                if (rp)
                    break;
            }
            if (ms >= g_timeout_ms && rp == NULL)
            {
                std::cout << l->name() << "接收超时:" << std::to_string(g_timeout_ms) << std::endl;
                if (tfn != nullptr)
                {
                    tfn(l);
                }
            }
        }
        // 4.应答回调
        if (rp != NULL && g)
        {
            g(l, rp);
        }
        l->OnLinkRecv = NULL;
    }
    return size;
}
int IMode::S2(LinkBase *l, PacketBuild b, PacketBase *r, PacketGet g, int g_timeout_ms, PacketTimeout tfn)
{
    int rsize = 0;
    if (l && b && r)
    {
        PacketBase *bs = b(l);
        if (bs)
        {
            rsize = IMode::S2(l, bs, r, g, g_timeout_ms, tfn);
            delete bs;
        }
    }
    return rsize;
}

// 3. 接收->发送
int IMode::W(LinkBase *l, PacketBase *r, PacketGet g, int g_timeout_ms, int counter, PacketTimeout tfn)
{
    if (l && r)
    {
        volatile int c = 0;
        volatile int ms = 0;
        PacketBase *rp = NULL;
        // packet接收回调
        l->OnLinkRecv = [&](LinkBase *link, LinkBuffer *buf, const char *arg)
        {
            rp = r->on_get((char *)buf->data(), buf->size(), (void *)arg);
            if (rp != NULL)
            {
                if (g)
                    g(l, rp);
                rp = NULL;
                ms = 0;
                c++;
            }
        };
        // 阻塞，等等超时
        while (ms < g_timeout_ms || g_timeout_ms == IMode::Wait_always)
        {
            if (rp != NULL && g_timeout_ms != IMode::Wait_always)
                break;
            if (c >= counter)
                break;
            ms += 10;
            usleep(10000);
        }
        l->OnLinkRecv = NULL;
        // 超时回调
        if (ms > g_timeout_ms && g_timeout_ms != IMode::Wait_always)
        {
            if (tfn != nullptr)
            {
                tfn(l);
            }
        }
    }
    return 0;
}
